package com.dong.juc;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;

/**
 * description
 *
 * @author Administrator 2021/08/25 18:32
 */
public class FIFOLock {

    /**
     * <p>
     * 通过LockSupport 实现先进先出锁
     * </p>
     * 
     * @author Administrator 2021/08/25 18:38
     */
    class FIFOMutex {
        private final AtomicBoolean locked = new AtomicBoolean(false);
        private final Queue<Thread> waiters
                = new ConcurrentLinkedQueue<Thread>();

        public void lock() {
            boolean wasInterrupted = false;
            Thread current = Thread.currentThread();
            waiters.add(current);

            // Block while not first in queue or cannot acquire lock
            while (waiters.peek() != current ||
                    !locked.compareAndSet(false, true)) {
                LockSupport.park(this);
                if (Thread.interrupted()) // ignore interrupts while waiting
                {
                    wasInterrupted = true;
                }
            }

            waiters.remove();
            if (wasInterrupted)          // reassert interrupt status on exit
            {
                current.interrupt();
            }
        }

        public void unlock() {
            locked.set(false);
            LockSupport.unpark(waiters.peek());
        }
    }

}
